package com.wqiuqiu.gulimall.ware.service.impl;

import com.wqiuqiu.common.R;
import com.wqiuqiu.common.constant.WareConstant;
import com.wqiuqiu.common.to.SkuInfoTo;
import com.wqiuqiu.gulimall.ware.entity.PurchaseDetailEntity;
import com.wqiuqiu.gulimall.ware.entity.WareSkuEntity;
import com.wqiuqiu.gulimall.ware.feign.ProductFeignService;
import com.wqiuqiu.gulimall.ware.service.PurchaseDetailService;
import com.wqiuqiu.gulimall.ware.service.WareSkuService;
import com.wqiuqiu.gulimall.ware.vo.DoneDetailVo;
import com.wqiuqiu.gulimall.ware.vo.MergePurchaseVo;
import com.wqiuqiu.gulimall.ware.vo.PurchaseDoneVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wqiuqiu.common.PageUtils;
import com.wqiuqiu.common.Query;

import com.wqiuqiu.gulimall.ware.dao.PurchaseDao;
import com.wqiuqiu.gulimall.ware.entity.PurchaseEntity;
import com.wqiuqiu.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    PurchaseDetailService purchaseDetailService;
    @Autowired
    WareSkuService wareSkuService;
    @Autowired
    ProductFeignService productFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryUnreceiveList(Map<String, Object> params) {
        List<PurchaseEntity> purchaseEntities = this.list(new QueryWrapper<PurchaseEntity>()
                .eq("status", WareConstant.purchaseStatus.NEWBUILD.getCode()).or()
                .eq("status", WareConstant.purchaseStatus.ALLOCATED.getCode()));
        PageUtils pageUtils = new PageUtils(this.page(new Query<PurchaseEntity>().getPage(params)));
        pageUtils.setList(purchaseEntities);
        return pageUtils;
    }

    @Override
    public boolean mergePurchaseList(MergePurchaseVo mergePurchaseVo) {
        List<Long> items = mergePurchaseVo.getItems();
        //如果采购需求的状态是正在采购或者后面状态，则不能合并（前端未做好，这里后端做了一个冗余查询来判断状态）
        Collection<PurchaseDetailEntity> purchaseDetailEntities1 = purchaseDetailService.listByIds(items);
        for (PurchaseDetailEntity purchaseDetailEntity : purchaseDetailEntities1) {
            if (purchaseDetailEntity.getStatus() != WareConstant.purchaseDetailStatus.NEWBUILD.getCode() &&
                    purchaseDetailEntity.getStatus() != WareConstant.purchaseDetailStatus.ALLOCATED.getCode())
                return false;
        }
        Long purchaseId = mergePurchaseVo.getPurchaseId();
        PurchaseEntity purchaseEntity = null;
        if (purchaseId == null) {
            //合并到一个新的采购单
            purchaseEntity = new PurchaseEntity();
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setStatus(WareConstant.purchaseStatus.NEWBUILD.getCode());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        } else {
            purchaseEntity = this.getById(purchaseId);
            //如果采购单的状态是已领取或者后面状态，则不能合并（前端已经做好）
            if (purchaseEntity.getStatus() != WareConstant.purchaseStatus.NEWBUILD.getCode()
                    && purchaseEntity.getStatus() != WareConstant.purchaseStatus.ALLOCATED.getCode()){

                return false;
            }
        }
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> purchaseDetailEntities = items.stream().map(obj -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            purchaseDetailEntity.setId(obj);
            //已分配
            purchaseDetailEntity.setStatus(WareConstant.purchaseDetailStatus.ALLOCATED.getCode());
            purchaseDetailEntity.setPurchaseId(finalPurchaseId);
            return purchaseDetailEntity;
        }).collect(Collectors.toList());

        purchaseDetailService.updateBatchById(purchaseDetailEntities);
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
        return true;
    }

    @Transactional
    @Override
    public void receivePurchaseList(List<Long> ids) {
        //1.确认采购单的状态
        //TODO 如果采购单的状态为新建，采购人员还没有分配，那么该采购单就无法被采购人员 领取
        Collection<PurchaseEntity> purchaseEntities = this.listByIds(ids);
        List<PurchaseEntity> collect = purchaseEntities.stream().filter(obj -> {
            return obj.getStatus() == WareConstant.purchaseStatus.NEWBUILD.getCode() || obj.getStatus() == WareConstant.purchaseStatus.ALLOCATED.getCode();
        }).map(obj -> {
                    obj.setStatus(WareConstant.purchaseStatus.RECEIVED.getCode());
                    obj.setUpdateTime(new Date());
                    return obj;
                }
        ).collect(Collectors.toList());
        //修改采购单的状态
        this.updateBatchById(collect);
        //改变采购项的状态
        List<PurchaseDetailEntity> purchaseDetailEntities = this.baseMapper.findListByPurchaseId(ids);
        purchaseDetailEntities = purchaseDetailEntities.stream().map(obj -> {
            obj.setStatus(WareConstant.purchaseDetailStatus.BUYING.getCode());
            return obj;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(purchaseDetailEntities);
    }

    @Transactional
    @Override
    public void donePurchase(PurchaseDoneVo purchaseDoneVo) {
        Long id = purchaseDoneVo.getId();
        PurchaseEntity purchaseEntity = this.getById(id);
        //对于已经完成的采购单
        if (purchaseEntity.getStatus() == WareConstant.purchaseStatus.COMPLETED.getCode()){
            //TODO 返回提示
            return;
        }
        purchaseEntity.setUpdateTime(new Date());
        List<DoneDetailVo> items = purchaseDoneVo.getItems();
        //得到采购项的id
        List<Long> ids = items.stream().map(obj -> {
            return obj.getItemId();
        }).collect(Collectors.toList());
        Collection<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.listByIds(ids);
        int i = 0;
        boolean isError = false;
        List<WareSkuEntity> wareSkuEntities = new ArrayList<>();
        for (PurchaseDetailEntity purchaseDetailEntity : purchaseDetailEntities) {
            purchaseDetailEntity.setStatus(items.get(i).getStatus());
            if (items.get(i).getStatus() == WareConstant.purchaseDetailStatus.FAILED.getCode()){
                //TODO 有异常以及异常原因，只要一个采购项有问题，整个采购单的状态为有异常
                isError = true;
            }else {
                //没有异常的采购项更新仓库
                WareSkuEntity wareSkuEntity = new WareSkuEntity();
                wareSkuEntity.setWareId(purchaseDetailEntity.getWareId());
                wareSkuEntity.setSkuId(purchaseDetailEntity.getSkuId());
                wareSkuEntity.setStock(purchaseDetailEntity.getSkuNum());
                //TODO 锁定库存，要设置为0，如果不设置就是NULL，后面计算库存时（stock-NULL）值，结果为NULL，会有异常。
                wareSkuEntity.setStockLocked(0);
                // TODO 调用远程服务
                try {
                    R r = productFeignService.info(purchaseDetailEntity.getSkuId());
                    if (r.getCode() == 0){
                        HashMap<String, Object> skuInfo = (HashMap<String, Object>) r.get("skuInfo");
                        wareSkuEntity.setSkuName((String) skuInfo.get("skuName"));
                    }
                }catch (Exception e){
                    log.error("远程调用失败!");
                }
                wareSkuEntities.add(wareSkuEntity);
            }
            i++;
        }
        //更新采购单的状态
        if (isError){
            purchaseEntity.setStatus(WareConstant.purchaseStatus.EXCEPTION.getCode());
        }else {
            purchaseEntity.setStatus(WareConstant.purchaseStatus.COMPLETED.getCode());
        }
        this.updateById(purchaseEntity);
        //更新采购项
        purchaseDetailService.updateBatchById(purchaseDetailEntities);
        //更新仓库
        wareSkuService.updateWare(wareSkuEntities);
    }

}